﻿using System;

namespace MyMailWp8.Protocol
{
    public enum CMPopState
    {
        CMPOP_Init = 0,
        CMPOP_Login = 10,
        CMPOP_List = 20,
        CMPOP_ListEnd = 25,
        CMPOP_Recv = 30,
        CMPOP_RecvedOneMail = 31,
        CMPOP_FetchAttachement = 40,
        CMPOP_RecvedOneAttachment = 41,
        CMPOP_RecvedOneAttachmentConvertList = 42,
        CMPOP_Ems = 50,
        CMPOP_EmsEnd = 51,
        CMPOP_Quit = 60
    };

    public enum CMSmtpState
    {
        CMSmtp_Init = 0,
        CMSmtp_Login = 10,
        CMSmtp_Send = 40,
        CMSmtp_SendDATA = 41,
        CMSmtp_SendEFWD = 42,
        CMSmtp_SendOneMail = 45,
        CMSmtp_Quit = 50
    };

    /// <summary>
    /// 执行出错时引发该事件
    /// </summary>
    /// <param name="error">错误字符串</param>
    /// <param name="errCode">错误编码</param>
    public delegate void TransportEventHandler(string error, int errCode);

    public delegate void AttachmentDownloadProcessEventHandler(Attachment attachment);

    internal class CMPopBase
    {
        public AsyncSocketClient _sockClient;

        // Notify the callee or user of this class through a custom event
        internal event CMPopStateEventHandler CMPopSmtpStateChanged;

        internal event TransportEventHandler TransportEvent;

        internal event AttachmentDownloadProcessEventHandler AttachmentDownloadProcessEvent;

        private System.Object lockObject = new System.Object();

        public CMPopBase(AsyncSocketClient sockClient)
        {
            _sockClient = sockClient;
        }

        public void SendData(String nStr)
        {
            try
            {
                _sockClient.SendData(nStr);
            }
            catch (PESocketException ex)
            {
                callErrorTransportEvent(ex.Message, ex.ErrCode);
            }
        }

        public void ReceiveData()
        {
            try
            {
                _sockClient.ReceiveData();
            }
            catch (PESocketException ex)
            {
                callErrorTransportEvent(ex.Message, ex.ErrCode);
            }
        }

        public void ChangeCMPopSmtpState(int nState)
        {
            if (CMPopSmtpStateChanged != null)
                CMPopSmtpStateChanged(nState);
        }

        public virtual int ParseData(String inString)
        {
            return 0;
        }

        public virtual int ProcessReceiveSucess()
        {
            return 0;
        }

        public virtual int ProcessSendSucess()
        {
            return 0;
        }

        public virtual int ProcessSendFailed()
        {
            return 0;
        }

        [Obsolete()]
        protected Object GetAccountInfo()
        {
            //Account account = null;
            //PeDataModel peDataModel = PEDBManager.Instance().peDataModel;
            //account = peDataModel.Get139Account();

            return null;
        }

        protected virtual int ParseCMPopErr(string inString)
        {
            int ret = 0; //success
            if (string.IsNullOrEmpty(inString))
                return ret;
            try
            {
                if (inString.ToUpper().StartsWith("-ERR"))
                {
                    string ErrCode = inString.Substring(5, 3);
                    ret = Convert.ToInt32(ErrCode);
                }
            }
            catch (Exception e)
            {
            }
            return ret;
        }

        protected string PostServerRetError(int errCode, string strPrefix = null)
        {
            string strErr = "";
            if (string.IsNullOrEmpty(strPrefix) == false)
                strErr = strPrefix;
            switch (errCode)
            {
                case 0:
                    strErr += "成功";
                    break;
                case 404:
                    strErr += "邮件已经过期";
                    break;
                case 416:
                    strErr += "不支持预览的文件类型";
                    break;
                case 501:
                    strErr += "邮件已过期,转发失败!";
                    break;

                case 451:
                    strErr += "请手动填写邮箱参数";
                    break;
                case 452:
                    strErr += "您已超过最大绑定邮箱数量";
                    break;
                case 453:
                    strErr += "邮箱不存在";
                    break;
                case 455:
                    strErr += "邮箱绑定失败,请检查帐户密码并确保pop服务已开启";
                    break;

                case (int)SockMessageType.ConnectFail:
                    strErr += "网络连接失败！";
                    break;
                case (int)SockMessageType.ReceiveFail:
                    strErr += "接收网络数据失败！";
                    break;
                case (int)SockMessageType.SendFail:
                    strErr += "发送数据失败";
                    break;
                case (int)SockMessageType.LoginFail:
                    strErr += "登录邮箱服务器失败";
                    break;
                case (int)SockMessageType.ListFail:
                    strErr += "获取邮件失败";
                    break;
                case (int)SockMessageType.UidlFail:
                    strErr += "获取邮件失败";
                    break;
                case (int)SockMessageType.DataError:
                    strErr += "邮件数据错误";
                    break;
                default:
                    break;
            }
            callErrorTransportEvent(strErr, errCode);
            return strErr;
        }

        public void resetEvent()
        {
            lock (lockObject)
            {
                this.TransportEvent = null;
                this.AttachmentDownloadProcessEvent = null;
            }
        }

        public void callErrorTransportEvent(string strErr, int errCode)
        {
            lock (lockObject)
            {
                if (TransportEvent != null)
                {
                    TransportEvent(strErr, errCode);
                }
            }
        }

    }//cls
}